/**
 * @file sm2.h
 * @brief This header file contains declarations and documentation for the functions of SM2.
 *
 * Functions:
 * - sm2_keygen(): Generate a pair of SM2 cryptographic keys.
 * - sm2_compute_z(): Compute the Z value for the SM2 algorithm.
 * - sm2_compute_e(): Compute the preprocessed E value for the SM2 algorithm.
 * - sm2_keydepair(): Derive the SM2 key pair from a given point.
 * - sm2_sign(): Sign a message using the SM2 algorithm.
 * - sm2_verify(): Verify the authenticity of a signed message using the SM2 algorithm.
 * - sm2_encrypt(): Encrypt a message using the SM2 algorithm.
 * - sm2_decrypt(): Decrypt a ciphertext using the SM2 algorithm.
 * - sm2_sig_to_der(): Convert an SM2 signature to DER-encoded format.
 * - sm2_sig_from_der(): Convert a DER-encoded SM2 signature to its original format.
 * - sm2_ciptext_to_der(): Convert an SM2 ciphertext to DER-encoded format.
 * - sm2_ciptext_from_der(): Convert a DER-encoded SM2 ciphertext to its original format.
 */

#ifndef SM_SM2_H
#define SM_SM2_H

#include "ecc.h"

/**
 * @brief Generate a pair of SM2 cryptographic keys.
 * @param privkey The output buffer to store the private key.
 * @param pubkey The output buffer to store the public key.
 * @param inf The elliptic curve information.
 */
void sm2_keygen(sm2_bn *privkey, sm2_point *pubkey, curve_inf inf);

/**
 * @brief Compute the Z value for the SM2 algorithm.
 * @param z The output buffer to store the computed Z value.
 * @param id The identification string.
 * @param pubkey The public key point.
 */
void sm2_compute_z(u8 *z, const sm2_public_key *publickey, const char *id, u64 idlen);

/**
 * @brief Compute the preprocessed E value for the SM2 algorithm.
 * @param dst The output buffer to store the computed E value.
 * @param z The Z value.
 * @param msq The message to be signed.
 */
void sm2_compute_e(u8 *dst, const u8 *z, const u8 *msq, const u64 msqlen);

/**
 * @brief Derive the SM2 key pair from a given point.
 * @param output The output buffer to store the derived key pair.
 * @param p The given point.
 * @param klen The length of the output key pair in bytes.
 */
void sm2_keydepair(u8 *output, point p, u32 klen);

/**
 * @brief Sign a message using the SM2 algorithm.
 * @param sig The output buffer to store the generated signature.
 * @param privkey The private key.
 * @param dgst The preprocessed E value.
 */

void sm2_sign_init(u8 *dgst, const sm2_public_key *pubkey, const char *id, u64 idlen, const u8 *msq, u64 msqlen);

void sm2_verify_init(u8 *dgst, const sm2_public_key *pubkey, const char *id, u64 idlen, const u8 *msq, u64 msqlen);

void sm2_sign(sm2_signature *sig, const sm2_private_key *prikey, const u8 *dgst);

/**
 * @brief Verify the authenticity of a signed message using the SM2 algorithm.
 * @param sig The signature to be verified.
 * @param publickey The public key.
 * @param dgst The preprocessed E value.
 * @return 1 if the signature is valid, 0 otherwise.
 */
int sm2_verify(const sm2_signature *sig, const sm2_public_key *publickey, const u8 *dgst);

/**
 * @brief Encrypt a message using the SM2 algorithm.
 * @param ciphertext The output buffer to store the encrypted ciphertext.
 * @param publickey The public key of the recipient.
 * @param msq The message to be encrypted.
 */
void sm2_encrypt(sm2_ciptext *ciphertext, const sm2_public_key *publickey, const char *msq);

/**
 * @brief Decrypt a ciphertext using the SM2 algorithm.
 * @param plaintext The output buffer to store the decrypted plaintext.
 * @param ciphertext The ciphertext to be decrypted.
 * @param privatekey The private key.
 * @return 1 if decryption is successful, 0 otherwise.
 */
int sm2_decrypt(u8 *plaintext, const sm2_private_key *prikey, const sm2_ciptext *ciphertext);

/**
 * @brief Convert an SM2 signature to DER-encoded format.
 * @param sig The signature to be converted.
 * @param dst The output buffer to store the DER-encoded signature.
 * @param dstl The length of the output buffer.
 */
void sm2_sig_to_der(sm2_signature sig, u8 **dst, u64 *dstl);

/**
 * @brief Convert a DER-encoded SM2 signature to its original format.
 * @param sig The output buffer to store the converted signature.
 * @param src The DER-encoded signature.
 * @param srcl The length of the DER-encoded signature.
 */
void sm2_sig_from_der(sm2_signature *sig, const u8 **src, u64 *srcl);

/**
 * @brief Convert an SM2 ciphertext to DER-encoded format.
 * @param ct The ciphertext to be converted.
 * @param dst The output buffer to store the DER-encoded ciphertext.
 * @param dstl The length of the output buffer.
 */
void sm2_ciptext_to_der(sm2_ciptext ct, u8 **dst, u64 *dstl);

/**
 * @brief Convert a DER-encoded SM2 ciphertext to its original format.
 * @param ct The output buffer to store the converted ciphertext.
 * @param src The DER-encoded ciphertext.
 * @param srcl The length of the DER-encoded ciphertext.
 */
void sm2_ciptext_from_der(sm2_ciptext *ct, const u8 **src, u64 *srcl);

#endif